<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>
    Yaf---加载规则插件使用 |
    
    无敌小笼包</title>
  
    <link rel="shortcut icon" href="/favicon.png">
  
  <link rel="stylesheet" href="/css/style.css">
  
    <link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">
  
  <script src="/js/pace.min.js"></script>
</head>

<body>
<main class="content">
  <section class="outer">
  <article id="post-yaf02" class="article article-type-post" itemscope itemprop="blogPost">

  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      Yaf---加载规则插件使用
    </h1>
  

      </header>
    

    
      <div class="article-meta">
        <a href="/2016/07/29/yaf02/" class="article-date">
  <time datetime="2016-07-29T14:22:43.000Z" itemprop="datePublished">2016-07-29</time>
</a>
        
  <div class="article-category">
    <a class="article-category-link" href="/categories/Frame/">Frame</a>
  </div>

      </div>
    

    <div class="article-entry" itemprop="articleBody">
      
      
      
        <p>Yaf在自启动的时候, 会通过SPL注册一个自己的Autoloader, 出于性能的考虑, 对于框架相关的MVC类, Yaf Autoloader只以目录映射的方式尝试一次.<br><a id="more"></a></p>
<table>
<thead>
<tr>
<th>类型</th>
<th>后缀</th>
<th>映射路径 </th>
</tr>
</thead>
<tbody>
<tr>
<td>控制器</td>
<td>Controller</td>
<td>默认模块下为{项目路径}/controllers/, 否则为{项目路径}/modules/{模块名}/controllers/</td>
</tr>
<tr>
<td>数据模型</td>
<td>Model</td>
<td>{项目路径}/models/</td>
</tr>
<tr>
<td>插件</td>
<td>Plugin</td>
<td>{项目路径}/plugins/</td>
</tr>
</tbody>
</table>
<h3 id="一个简单的自我理解"><a href="#一个简单的自我理解" class="headerlink" title="一个简单的自我理解"></a>一个简单的自我理解</h3><pre><code>&lt;?php
class IndexController extends Yaf_Controller_Abstract {
    public function indexAction() {//默认Action

    $mod = new TserModel(); //自动加载model下面的test.php文件

    $mod-&gt;query(); //调用TestModel里的query方法

    $user = new UserPlugin(); //自动加载plugins下面的user.php文件

    $this-&gt;getView()-&gt;assign(&quot;title&quot;, &quot;Hello Yaf&quot;);

    $this-&gt;getView()-&gt;assign(&quot;content&quot;, &quot;Hello Yaf Content&quot;);
}
</code></pre><h3 id="类的自动加载规则"><a href="#类的自动加载规则" class="headerlink" title="类的自动加载规则"></a>类的自动加载规则</h3><p>而类的加载规则, 都是一样的: Yaf规定类名中必须包含路径信息, 也就是以下划线”_”分割的目录信息. Yaf将依照类名中的目录信息, 完成自动加载. 如下的例子, 在没有申明本地类的情况下:</p>
<pre><code>public function indexAction() {

  $upload = new upload_aliyun();

   //这个就会按下划线分割目录来寻找文件，所以他会寻找 \library\upload\aliyun.php
}
</code></pre><p>先这么简单理解，还有一个registerLocalNamespace的内容，后续再来说一说，怕混了。</p>
<h3 id="手动载入"><a href="#手动载入" class="headerlink" title="手动载入"></a>手动载入</h3><p><code>Yaf_Loader::import</code></p>
<p>导入一个PHP文件, 因为Yaf_Loader::import只是专注于一次包含, 所以要比传统的require_once性能好一些<br>示例：<br>    &lt;?php<br>      //绝对路径<br>      Yaf_Loader::import(“/usr/local/foo.php);<br>      //相对路径, 会在APPLICATION_PATH.”/library”下加载<br>      Yaf_loader::import(“plugins/User.php”);<br>    ?&gt;</p>
<p><img src="/blog-img/yafa.bmp" alt="" title="phpinfo显示成功螃蟹图标再现"></p>
<h3 id="使用Boostrap"><a href="#使用Boostrap" class="headerlink" title="使用Boostrap"></a>使用Boostrap</h3><p>Bootstrap, 也叫做引导程序. 它是Yaf提供的一个全局配置的入口, 在Bootstrap中, 你可以做很多全局自定义的工作.</p>
<p>使用Bootstrap</p>
<p>在一个Yaf_Application被实例化之后, 运行(Yaf_Application::run)之前, 可选的我们可以运行Yaf_Application::bootstrap<br>改写index.php文件如下：</p>
<pre><code>&lt;?php
define(&quot;APP_PATH&quot;, realpath(dirname(__FILE__)));

$app = new Yaf_Application(APP_PATH . &quot;/conf/application.ini&quot;);

$app-&gt;bootstrap()-&gt;run();

当bootstrap被调用的时刻, Yaf_Application就会默认的在APPLICATION_PATH下, 
寻找Bootstrap.php,而这个文件中, 必须定义一个Bootstrap类, 
而这个类也必须继承自Yaf_Bootstrap_Abstract.实例化成功之后, 
所有在Bootstrap类中定义的, 以_init开头的方法, 都会被依次调用, 
而这些方法都可以接受一个Yaf_Dispatcher实例作为参数.也可以通过在配置文件中修改application.bootstrap来变更Bootstrap类的位置.
</code></pre><blockquote>
<p>简单的示例Bootstrap.php</p>
</blockquote>
<pre><code>&lt;?php
  class Bootstrap extends Yaf_Bootstrap_Abstract {
    public function _initConfig(){
      $config = Yaf_Application::app()-&gt;getConfig();
      Yaf_Registry::set(&quot;config&quot;, $config);
    }
  public function _initDefaultName(Yaf_Dispatcher $dispatcher) {
   $dispatcher-&gt;setDefaultModule(&quot;Index&quot;)-&gt;setDefaultController(&quot;Index&quot;)-&gt;setDefaultAction(&quot;index&quot;);
   }
}
</code></pre><p><img src="/blog-img/yafb.bmp" alt="" title="phpinfo显示成功螃蟹图标再现"></p>
<h3 id="插件使用"><a href="#插件使用" class="headerlink" title="插件使用"></a>插件使用</h3><p>Yaf支持用户定义插件来扩展Yaf的功能, 这些插件都是一些类. 它们都必须继承自Yaf_Plugin_Abstract. 插件要发挥功效, 也必须现实的在Yaf中进行注册, 然后在适当的实际, Yaf就会调用它.</p>
<blockquote>
<p>Yaf 支持的Hook</p>
</blockquote>
<table>
<thead>
<tr>
<th>名称</th>
<th>触发时机</th>
<th>说明 </th>
</tr>
</thead>
<tbody>
<tr>
<td>routerStartup</td>
<td>在路由之前触发</td>
<td>这个是7个事件中, 最早的一个. 但是一些全局自定的工作, 还是应该放在Bootstrap中去完成</td>
</tr>
<tr>
<td>routerShutdown</td>
<td>路由结束之后触发</td>
<td>此时路由一定正确完成, 否则这个事件不会触发</td>
</tr>
<tr>
<td>dispatchLoopStartup</td>
<td>分发循环开始之前被触发</td>
<td></td>
</tr>
<tr>
<td>preDispatch</td>
<td>分发之前触发</td>
<td>如果在一个请求处理过程中, 发生了forward, 则这个事件会被触发多次</td>
</tr>
<tr>
<td>postDispatch</td>
<td>分发结束之后触发</td>
<td>此时动作已经执行结束, 视图也已经渲染完成. 和preDispatch类似, 此事件也可能触发多次</td>
</tr>
<tr>
<td>dispatchLoopShutdown</td>
<td>分发循环结束之后触发</td>
<td>此时表示所有的业务逻辑都已经运行完成, 但是响应还没有发送</td>
</tr>
</tbody>
</table>
<blockquote>
<p>　定义插件　</p>
</blockquote>
<p>插件类是用户编写的, 但是它需要继承自Yaf_Plugin_Abstract. 对于插件来说, 上一节提到的7个Hook, 它不需要全部关心, 它只需要在插件类中定义和上面事件同名的方法, 那么这个方法就会在该事件触发的时候被调用.<br>而插件方法, 可以接受俩个参数, Yaf_Request_Abstract实例和Yaf_Response_Abstract实例. 一个插件类<br>例子如下:</p>
<p><code>plugins/User.php</code></p>
<pre><code>&lt;?php
  class UserPlugin extends Yaf_Plugin_Abstract {
   public function routerStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstract $respons
  }
   public function routerShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstract $respo
  }
}
</code></pre><p><img src="/blog-img/yafc.bmp" alt="" title="phpinfo显示成功螃蟹图标再现"></p>
<blockquote>
<p>注册插件</p>
</blockquote>
<p>插件要生效, 还需要向Yaf_Dispatcher注册, 那么一般的插件的注册都会放在Bootstra中进行. 一个注册插件的例子如下:</p>
<pre><code>&lt;?php
class Bootstrap extends Yaf_Bootstrap_Abstract{
  public function _initPlugin(Yaf_Dispatcher $dispatcher) 
  {
    $user = new UserPlugin();
    $dispatcher-&gt;registerPlugin($user);
  }
}
</code></pre><p><img src="/blog-img/yafd.bmp" alt="" title="phpinfo显示成功螃蟹图标再现"></p>
<blockquote>
<p>目录</p>
</blockquote>
<p>  一般的, 插件应该放置在APPLICATION_PATH下的plugins目录, 这样在自动加载的时候, 加载器通过类名,发现这是个插件类, 就会在这个目录下查找.当然, 插件也可以放在任何你想防止的地方, 只要你能把这个类加载进来就可以</p>
<h3 id="获取参数"><a href="#获取参数" class="headerlink" title="获取参数"></a>获取参数</h3><p><code>Yaf_Request_Http</code></p>
<p>代表了一个实际的Http请求, 一般的不用自己实例化它, Yaf_Application在run以后会自动根据当前请求实例它，在控制器内可以使用$this-&gt;getRequest()来获取请求信息。更多Yaf_Request_Http类的内容可参见文档：</p>
<p><a href="http://www.laruence.com/manual/yaf.class.request.html#yaf.class.request.http" target="_blank" rel="noopener">http://www.laruence.com/manual/yaf.class.request.html#yaf.class.request.http</a></p>
<blockquote>
<p>使用示例</p>
</blockquote>
<pre><code>&lt;?php
class IndexController extends Yaf_Controller_Abstract {

  public function indexAction($name=&apos;&apos;, $value=&apos;&apos;) {

   print_r($this-&gt;getRequest()-&gt;getQuery());
}
</code></pre><p>扩展  <code>Yaf_Request_Http</code>，比如加上过滤，数据处理等。先在<code>library</code>定义一个<code>request</code>的类,再在<code>Bootstrap.php</code>里设置<code>Request</code><br>文件示例：<code>library/Request.php</code></p>
<p><img src="/blog-img/yafe.bmp" alt="" title="phpinfo显示成功螃蟹图标再现"></p>
<pre><code>&lt;?php
class Bootstrap extends Yaf_Bootstrap_Abstract{
        public function _initRequest(Yaf_Dispatcher $dispatcher)
    {
      $dispatcher-&gt;setRequest(new Request());
    }
}
</code></pre><p>  然后在控制器中可以使用$this-&gt;getRequest()-&gt;getQuery()来获取参数</p>
<pre><code>&lt;?php
class IndexController extends Yaf_Controller_Abstract {
  public function indexAction() {
     print_r($this-&gt;getRequest()-&gt;getQuery());
}
</code></pre><p>关于更多的该类的使用方法，可以参考：<br><a href="http://www.laruence.com/manual/yaf.class.request.html" target="_blank" rel="noopener">http://www.laruence.com/manual/yaf.class.request.html</a></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://blog.mango16.cc/2016/07/29/yaf02/" data-id="cjrbtw1zw002v6d8ha2m1s28w"
         class="article-share-link">分享</a>
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Yaf/">Yaf</a></li></ul>

    </footer>

  </div>

  
    
  <nav class="article-nav">
    
      <a href="/2016/07/30/yaf03/" class="article-nav-link">
        <strong class="article-nav-caption">前一篇</strong>
        <div class="article-nav-title">
          
            Yaf---Session | 模板 | 模型  | Cli模式
          
        </div>
      </a>
    
    
      <a href="/2016/07/28/yaf01/" class="article-nav-link">
        <strong class="article-nav-caption">后一篇</strong>
        <div class="article-nav-title">Yaf---写在前面</div>
      </a>
    
  </nav>


  

  
    
  <div class="gitalk" id="gitalk-container"></div>
  <link rel="stylesheet" href="https://unpkg.com/gitalk/dist/gitalk.css">
  <script src="https://unpkg.com/gitalk/dist/gitalk.min.js"></script>
  <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
  <script type="text/javascript">
      var gitalk = new Gitalk({
        clientID: 'caba8826a61790936307',
        clientSecret: '09a15037dcab30d9adf35a53ec6961939169f797',
        repo: 'm9rco.github.io',
        owner: 'm9rco',
        admin: ['m9rco'],
        // id: location.pathname,      // Ensure uniqueness and length less than 50
        id: md5(location.pathname),
        distractionFreeMode: false  // Facebook-like distraction free mode
      })

  gitalk.render('gitalk-container')
  </script>

  

</article>



</section>
  <footer class="footer">
  
  <div class="outer">
    <ul class="list-inline">
      <li>&copy; 2019 无敌小笼包</li>
      <i class="pulse"></i>
    </ul>
  </div>
</footer>

</main>
<aside class="sidebar">
  <button class="navbar-toggle"></button>

<nav class="navbar">
  
    <div class="logo">
      <a href="/"><img src="/images/hexo.svg" alt="无敌小笼包"></a>
    </div>
  
  <ul class="nav nav-main">
    
      <li class="nav-item">
        <a class="nav-item-link" href="/">主页</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/archives">归档</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/gallery">相册</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/nagging">叽咕</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/about">关于</a>
      </li>
    
    <li class="nav-item">
      <a class="nav-item-link nav-item-search" title="Search">
        <i class="fe fe-search"></i>
        搜索
      </a>
    </li>
  </ul>
</nav>

<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
        <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
          <i class="fe fe-feed"></i>
        </a>
      
    </li>
  </ul>
</nav>

<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
</aside>
  <script src="/js/jquery-2.0.3.min.js"></script>
<script src="/js/lazyload.min.js"></script>


  <script src="/fancybox/jquery.fancybox.min.js"></script>



  <script src="/js/search.js"></script>


<script src="/js/ocean.js"></script>

</body>
</html>